<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ESP32实时视频流</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
      color: white;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 20px;
    }
    
    .container {
      max-width: 1000px;
      width: 100%;
      background: rgba(0, 0, 0, 0.7);
      border-radius: 15px;
      overflow: hidden;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
      backdrop-filter: blur(10px);
    }
    
    header {
      background: rgba(0, 0, 0, 0.6);
      padding: 20px;
      text-align: center;
      border-bottom: 2px solid #ff6b6b;
    }
    
    h1 {
      font-size: 2.2rem;
      margin-bottom: 10px;
      color: #4facfe;
    }
    
    .subtitle {
      font-size: 1.1rem;
      opacity: 0.8;
    }
    
    .video-container {
      position: relative;
      padding: 20px;
    }
    
    #video-frame {
      width: 100%;
      max-height: 70vh;
      object-fit: contain;
      border-radius: 10px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
      background: #000;
    }
    
    .status-bar {
      display: flex;
      justify-content: space-between;
      padding: 15px 20px;
      background: rgba(0, 0, 0, 0.5);
      border-top: 1px solid #444;
    }
    
    .status-indicator {
      display: flex;
      align-items: center;
    }
    
    .indicator {
      width: 12px;
      height: 12px;
      border-radius: 50%;
      margin-right: 10px;
      background: #ff4757;
    }
    
    .indicator.connected {
      background: #2ed573;
      box-shadow: 0 0 10px #2ed573;
    }
    
    .fps-counter {
      background: rgba(255, 255, 255, 0.1);
      padding: 5px 15px;
      border-radius: 20px;
    }
    
    .controls {
      display: flex;
      justify-content: center;
      gap: 15px;
      padding: 20px;
    }
    
    .btn {
      padding: 12px 25px;
      border: none;
      border-radius: 50px;
      background: linear-gradient(to right, #4facfe 0%, #00f2fe 100%);
      color: white;
      font-weight: bold;
      cursor: pointer;
      transition: all 0.3s;
      box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
    }
    
    .btn:hover {
      transform: translateY(-3px);
      box-shadow: 0 6px 15px rgba(0, 0, 0, 0.3);
    }
    
    .btn:active {
      transform: translateY(1px);
    }
    
    .quality-btn {
      background: linear-gradient(to right, #ff7e5f, #feb47b);
    }
    
    .connection-info {
      padding: 15px 20px;
      background: rgba(0, 0, 0, 0.4);
      border-top: 1px solid #444;
      font-family: monospace;
    }
    
    footer {
      text-align: center;
      padding: 20px;
      opacity: 0.7;
      font-size: 0.9rem;
    }
    
    @media (max-width: 768px) {
      .container {
        border-radius: 10px;
      }
      
      h1 {
        font-size: 1.8rem;
      }
      
      .controls {
        flex-direction: column;
        align-items: center;
      }
      
      .btn {
        width: 80%;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <header>
      <h1>ESP32 实时视频监控</h1>
      <div class="subtitle">低延迟视频流传输系统</div>
    </header>
    
    <div class="video-container">
      <img id="video-frame" alt="实时视频流">
    </div>
    
    <div class="status-bar">
      <div class="status-indicator">
        <div class="indicator" id="connection-indicator"></div>
        <span id="connection-status">正在连接服务器...</span>
      </div>
      <div class="fps-counter">FPS: <span id="fps">0</span></div>
    </div>
    
    <div class="controls">
      <button class="btn quality-btn" id="quality-btn">高清模式</button>
      <button class="btn" id="fullscreen-btn">全屏显示</button>
    </div>
    
    <div class="connection-info">
      连接状态: <span id="ws-status">未连接</span><br>
      接收帧数: <span id="frame-count">0</span><br>
      最后更新时间: <span id="last-update">--:--:--</span>
    </div>
    
    <footer>
      ESP32视频流服务 &copy; 2023 | 基于Node.js和WebSocket技术
    </footer>
  </div>

  <script>
    // 获取DOM元素
    const videoFrame = document.getElementById('video-frame');
    const connectionIndicator = document.getElementById('connection-indicator');
    const connectionStatus = document.getElementById('connection-status');
    const fpsDisplay = document.getElementById('fps');
    const frameCountDisplay = document.getElementById('frame-count');
    const lastUpdateDisplay = document.getElementById('last-update');
    const wsStatus = document.getElementById('ws-status');
    const qualityBtn = document.getElementById('quality-btn');
    const fullscreenBtn = document.getElementById('fullscreen-btn');
    
    // 状态变量
    let frameCount = 0;
    let lastFrameTime = 0;
    let fps = 0;
    let isHighQuality = false;
    
    // 从URL参数获取WebSocket服务器地址
    const params = new URLSearchParams(window.location.search);
    let wsUrl = 'wss://lzdazhuang.cn/camera';
    
    // 如果当前是HTTPS，则使用WSS
    if (window.location.protocol === 'https:') {
      wsUrl = wsUrl.replace('ws://', 'wss://');
    }
    
    // 创建WebSocket连接
    let ws;
    
    function connectWebSocket() {
      ws = new WebSocket(wsUrl);
      ws.binaryType = 'arraybuffer';
      
      ws.onopen = () => {
        console.log('WebSocket连接成功');
        updateConnectionStatus('已连接', 'connected');
        wsStatus.textContent = '已连接';
      };
      
      ws.onerror = (error) => {
        console.error('WebSocket错误:', error);
        updateConnectionStatus('连接错误', 'error');
        wsStatus.textContent = '错误: ' + (error.message || '未知错误');
      };
      
      ws.onclose = () => {
        console.log('WebSocket连接关闭');
        updateConnectionStatus('连接已断开', 'disconnected');
        wsStatus.textContent = '已断开';
        // 尝试重新连接
        setTimeout(connectWebSocket, 3000);
      };
      
      ws.onmessage = (event) => {
        if (event.data instanceof ArrayBuffer) {
          processVideoFrame(event.data);
        }
      };
    }
    
    // 处理视频帧
    function processVideoFrame(frameData) {
      frameCount++;
      frameCountDisplay.textContent = frameCount;
      
      // 计算FPS
      const now = Date.now();
      if (lastFrameTime > 0) {
        const delta = now - lastFrameTime;
        fps = Math.round(1000 / delta);
        fpsDisplay.textContent = fps;
      }
      lastFrameTime = now;
      
      // 更新时间显示
      const timeString = new Date().toLocaleTimeString();
      lastUpdateDisplay.textContent = timeString;
      
      // 创建Blob URL
      const blob = new Blob([frameData], { type: 'image/jpeg' });
      const url = URL.createObjectURL(blob);
      
      // 更新图像源
      videoFrame.src = url;
      
      // 释放之前的URL
      if (videoFrame.previousSrc) {
        URL.revokeObjectURL(videoFrame.previousSrc);
      }
      videoFrame.previousSrc = url;
    }
    
    // 更新连接状态显示
    function updateConnectionStatus(text, className) {
      connectionStatus.textContent = text;
      connectionIndicator.className = 'indicator';
      connectionIndicator.classList.add(className);
    }
    
    // 全屏功能
    function toggleFullscreen() {
      if (!document.fullscreenElement) {
        document.documentElement.requestFullscreen().catch(err => {
          console.error('全屏请求失败:', err);
        });
        fullscreenBtn.textContent = '退出全屏';
      } else {
        document.exitFullscreen();
        fullscreenBtn.textContent = '全屏显示';
      }
    }
    
    // 质量切换
    function toggleQuality() {
      isHighQuality = !isHighQuality;
      qualityBtn.textContent = isHighQuality ? '流畅模式' : '高清模式';
      
      // 这里可以添加实际切换质量的逻辑
      if (ws && ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify({
          type: 'quality',
          value: isHighQuality ? 'high' : 'low'
        }));
      }
    }
    
    // 初始化
    function init() {
      connectWebSocket();
      
      // 添加事件监听
      fullscreenBtn.addEventListener('click', toggleFullscreen);
      qualityBtn.addEventListener('click', toggleQuality);
      
      // 初始状态
      updateConnectionStatus('正在连接...', 'connecting');
      
      // 退出全屏时更新按钮文字
      document.addEventListener('fullscreenchange', () => {
        if (!document.fullscreenElement) {
          fullscreenBtn.textContent = '全屏显示';
        }
      });
    }
    
    // 启动应用
    window.addEventListener('load', init);
  </script>
</body>
</html>